
#include "IndexManage.h"

IndexManager g_IndexFinder;


// 数据库函数
void AsyncProc_InsertIndex(CMsgTyped* pmsg, sql::Statement* pConn)
{
	if (!pConn)
	{
		return;
	}

	string roleNmae = pmsg->StringVal(); //wstring roleNmae = pmsg->WideStrVal();

	try
	{
		char sql[128];
		sprintf(sql, "insert into MailIndex values('%s')",roleNmae.c_str()); // WideStrAsUtf8(roleNmae).c_str()

		pConn->executeUpdate(sql);
	}
	catch(sql::SQLException & e)
    {
        cout << __LINE__ << "\n";
        cout << "# ERR: " << e.what() << "\n";
    }
}

void AsyncProc_DeleteIndex(CMsgTyped* pmsg, sql::Statement* pConn)
{
	if (!pConn)
	{
		return;
	}

	string roleNmae = pmsg->StringVal(); //wstring roleNmae = pmsg->WideStrVal();

	try
	{
		char sql[128];
		sprintf(sql, "delete from MailIndex where player = '%s'", roleNmae.c_str()); //WideStrAsUtf8

		pConn->executeUpdate(sql);
	}
	catch(sql::SQLException & e)
    {
        cout << __LINE__ << "\n";
        cout << "# ERR: " << e.what() << "\n";
    }
}

void AsyncProc_DeleteRubish(CMsgTyped* pmsg, sql::Statement* pConn)
{
	if (!pConn)
	{
		return;
	}

	try
	{
		pConn->executeUpdate("delete from MailTable where DATEDIFF(now(), SendTime) > 15"); //天 15 30
	}
	catch(sql::SQLException & e)
    {
        cout << __LINE__ << "\n";
        cout << "# ERR: " << e.what() << "\n";
    }

    // 删除系统邮件垃圾
    try
	{
		pConn->executeUpdate("delete from SysMailStat where DATEDIFF(now(), SendTime) > 15"); //天 15 30
	}
	catch(sql::SQLException & e)
    {
        cout << __LINE__ << "\n";
        cout << "# ERR: " << e.what() << "\n";
    }

    try
	{
		pConn->executeUpdate("delete from SysMailTable where DATEDIFF(now(), SendTime) > 15");  //天 15 30
	}
	catch(sql::SQLException & e)
    {
        cout << __LINE__ << "\n";
        cout << "# ERR: " << e.what() << "\n";
    }
}

void AsyncProc_LoadIndex(CMsgTyped* pmsg, sql::Statement* pConn)
{
	if (!pConn )
	{
		return;
	}

	int location = pmsg->IntVal();

    MysqlResult res;

	try
	{
		res.dataSet = pConn->executeQuery("select * from MailIndex");

		if (!res.dataSet) return;

        while (res.dataSet->next())
        {
            string player = res.dataSet->getString("player").c_str(); //wstring Utf8AsWideStr

            g_IndexFinder.AddLocation(location, player.c_str());
        }
	}
	catch(sql::SQLException & e)
    {
        cout << __LINE__ << "\n";
        cout << "# ERR: " << e.what() << "\n";
    }
}

IndexManager::IndexManager()
{

}

IndexManager::~IndexManager()
{

}

int IndexManager::FindRoleNoCreate(const char* playerName)
{
	if (!playerName) return -1;

	int retValue = -1;

	Lock();

	std::map<string, int, MapStringComp>::iterator it = m_roleMap.find(playerName); //wstring //MapWStringComp
	if (it != m_roleMap.end())
	{
		retValue = it->second;
	}

	Unlock();

	return retValue;
}

int IndexManager::FindRole(const char* playerName)
{
	if (!playerName) return -1;

	int retValue = -1;

	Lock();

	std::map<string, int, MapStringComp>::iterator it = m_roleMap.find(playerName); //wstring //MapWStringComp
	if (it != m_roleMap.end())
	{
		retValue = it->second;
	}
	else
	{
		// 如果找不到位置id， 分配一个给他，并且在对应的数据库里面插入index
		size_t location = -1;
		int leastRoleCount = 100000000;

		for (size_t i=0; i < m_locations.size(); i++)
		{
			if (m_locations[i].roleCount < leastRoleCount)
			{
				leastRoleCount = m_locations[i].roleCount;
				location = i;
			}
		}

		// 找到位置了
		if (location != -1)
		{
			retValue = m_locations[location].location;

			AddLocation(retValue, playerName);

			// 创建这个location index
			CMsgTyped param;
			param.SetString(playerName); //SetWideStr
			g_pGame->Call(retValue, AsyncProc_InsertIndex, &param);
		}
	}

	Unlock();

	return retValue;
}

int IndexManager::DeleteRole(const char* playerName)
{
	if (!playerName) return 0;

	Lock();

	std::map<string, int, MapStringComp>::iterator it = m_roleMap.find(playerName); //wstring //MapWStringComp
	if (it != m_roleMap.end())
	{
		int location = it->second;

		CMsgTyped param;
		param.SetString(playerName); //SetWideStr
		g_pGame->Call(location, AsyncProc_DeleteIndex, &param);

		// 删除索引
		m_roleMap.erase(it);
	}

	Unlock();

	return 0;
}

int IndexManager::CheckDeleteRubish()
{
	Lock();

	int poolCount[200];
	int count = 200;
	g_pGame->QueryPoolList(2, poolCount, count);

	for (size_t i=0; i < 200; i++)
	{
		if (poolCount[i] == 0)
		{
			break;
		}

		// 添加记录
		LocationState state;
		state.location = poolCount[i];
		state.roleCount = 0;

		m_locations.push_back(state);

		// 投递请求
		CMsgTyped param;
		param.SetInt(state.location);
		g_pGame->Call(poolCount[i], AsyncProc_DeleteRubish, &param);
	}

	Unlock();

	return 0;
}

void IndexManager::ProcessListMail()
{

}

void IndexManager::LoadLocation(IGlobal* pGame)
{
	Lock();

	int poolCount[200];
	int count = 200;
	g_pGame->QueryPoolList(2, poolCount, count);

	for (size_t i=0; i < 200; i++)
	{
		if (poolCount[i] == 0)
		{
			break;
		}

		// 添加记录
		LocationState state;
		state.location = poolCount[i];
		state.roleCount = 0;

		m_locations.push_back(state);

		// 投递请求
		CMsgTyped param;
		param.SetInt(state.location);
		g_pGame->Call(poolCount[i], AsyncProc_LoadIndex, &param);
	}

	Unlock();
}

void IndexManager::AddLocation(int location, const char* playerName)
{
	if (!playerName) return;

	Lock();

	m_roleMap[playerName] = location;

	for (size_t i=0; i < m_locations.size(); i++)
	{
		if (m_locations[i].location == location)
		{
			m_locations[i].roleCount ++;
			break;
		}
	}

	Unlock();
}

void IndexManager::GetLocationList(std::vector<int>& list)
{
	list.clear();

	Lock();

	for (size_t i=0; i < m_locations.size(); i++)
	{
		list.push_back(m_locations[i].location);
	}

	Unlock();
}

